﻿using EMC.VISITOR.Application;
using Magicodes.ExporterAndImporter.Excel.Utility.TemplateExport;
using Masuit.Tools;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using SqlSugar;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinUserInfoBatchGetRequest.Types;

namespace EMC.VISITOR.Plugin.GoView
{
    /// <summary>
    /// 订单服务
    /// </summary>
    [UnifyProvider("GoView")]
    [ApiDescriptionSettings(GoViewConst.GroupName, Module = "goview", Name = "project", Order = 100)]
    public partial class BigScreeService : IDynamicApiController, ITransient
    {
        private readonly string currentHost = App.GetConfig<string>("CurrentHost");
        private readonly SqlSugarRepository<GoViewPro> _rep;

        public BigScreeService(SqlSugarRepository<GoViewPro> rep)
        {
            _rep = rep;

        }

        [HttpGet]
        public async Task<dynamic> LoadVisitor()
        {
            var _db = _rep.Context;
            var today = DateTime.Today;
            var tsCardNos = await CommonUtil.GetConfigRemarkSplits("visitor_hk_tscardnos", ",");

            //var vTypes = new VisitorType[] { VisitorType.Usual, VisitorType.Driver, VisitorType.Build /*, VisitorType.Customer, VisitorType.GovernmentPersonnel*/ };
            //今日計劃來訪用戶
            Expression<Func<VisitLog, bool>> planVisitorExpression = c => (c.VisitTime >= today && c.VisitTime < today.AddDays(1)) /*&& vTypes.Contains(c.Type)*/ && c.Status >= ProcessStatus.Agreed;

            var planVisitorCount = await _db.MyQueryable<VisitLog>().Where(planVisitorExpression).CountAsync();

            var planYbVisitorCount = await _db.MyQueryable<VisitLog>().Where(c => (c.VisitTime >= today && c.VisitTime < today.AddDays(1)) && c.Type == VisitorType.Usual).CountAsync();
            //實際到訪的訪客
            Expression<Func<VisitLog, bool>> realVisitorExpression = c => (c.VisitTime >= today && c.VisitTime < today.AddDays(1)) /*&& vTypes.Contains(c.Type)*/ && (c.Status >= ProcessStatus.HwAgreed);
            var realVisitorCount = await _db.MyQueryable<VisitLog>().Where(realVisitorExpression).CountAsync();

            //场内访客信息
            //Expression<Func<VisitLog, bool>> factoryInVisitorExpression = ; ;
            var factoryVisitors = await _db.MyQueryable<VisitLog>().Where(c => (c.VisitTime >= today && c.VisitTime < today.AddDays(1)) && c.Status >= ProcessStatus.WaitToEnter)
                .GroupBy(r => r.Type)
                .Select(r => new
                {
                    r.Type,
                    count = SqlFunc.AggregateCount(r.Type)
                }).ToListAsync();

            var realSGVisitorCount = await _db.MyQueryable<VisitLog>().Where(c => c.Type == VisitorType.Build && c.VisitTime.Value.ToString("yyyy-MM-dd") != today.ToString("yyyy-MM-dd") && c.Status >= ProcessStatus.WaitToEnter && c.WaitToEnterTime >= today && c.WaitToEnterTime < today.AddDays(1))
            .CountAsync();


            var visitorList = await _db.MyQueryable<VisitLog>().Where(r => r.VisitTime >= DateTime.Today && /*vTypes.Contains(r.Type) &&*/ r.Status < ProcessStatus.GoneOut).ToListAsync();

            return new
            {
                planVisitorCount = planVisitorCount + realSGVisitorCount,
                realVisitorCount = realVisitorCount + realSGVisitorCount,
                planYbVisitorCount = planYbVisitorCount, //計劃來訪的一般訪客
                ybVisitorCount = factoryVisitors.FirstOrDefault(r => r.Type == VisitorType.Usual) == null ? 0 : factoryVisitors.FirstOrDefault(r => r.Type == VisitorType.Usual)?.count,
                hcVisitorCount = factoryVisitors.FirstOrDefault(r => r.Type == VisitorType.Driver) == null ? 0 : factoryVisitors.FirstOrDefault(r => r.Type == VisitorType.Driver)?.count,
                sgVisitorCount = factoryVisitors.FirstOrDefault(r => r.Type == VisitorType.Build) == null ? 0 + realSGVisitorCount : realSGVisitorCount + factoryVisitors.FirstOrDefault(r => r.Type == VisitorType.Build)?.count,
                tsVisitorCount = factoryVisitors.Where(r => r.Type >= VisitorType.Customer).Sum(r => r.count),
                ////柱狀圖數據
                //echatData = new
                //{
                //    dimensions = new string[] { "visitor", "今日1計劃來訪", "今日已到訪" },
                //    source = vTypes.Select(r => new
                //    {
                //        visitor = r.GetDescription(),
                //        計劃來訪 = visitorList.Where(planVisitorExpression.And(c => c.Type == r).Compile()).Count(),
                //        已到訪 = visitorList.Where(realVisitorExpression.And(c => c.Type == r).Compile()).Count(),
                //    }).ToList()
                //}
            };

            //            { "dimensions":["visitor", "計劃來訪", "已到訪"],
            //            "source":[{ "product":"1月","data1":104,"data2":30},
            //{ "product":"2月","data1":56,"data2":56},{ "product":"3月",
            //                        "data1":136,"data2":36},{ "product":"4月","data1":86,"data2":6},{ "product":"5月","data1":98,"data2":10},{ "product":"6月","data1":86,"data2":70},{ "product":"7月","data1":77,"data2":57}]}
        }
        /// <summary>
        /// 当前场内访客信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<dynamic> CurrentFactoryVisInfos()
        {
            var _db = _rep.Context;
            var today = DateTime.Today;
            var now = DateTime.Now;
            var tsCardNos = await CommonUtil.GetConfigRemarkSplits("visitor_hk_tscardnos", ",");

            var query = _db.MyQueryable<VisitLog>()
                .LeftJoin<DoorInOutRecord>((u, doorRecord) => SqlFunc.ToString(u.Id) == doorRecord.personId)
                .LeftJoin<HKCrossRecord>((u, doorRecord, carRecord) => u.CarNo == carRecord.plateNo)
                .LeftJoin<SysUser>((u, doorRecord, carRecord, user) => u.LeaderId == user.Id)
                .LeftJoin<WchatMessage>((u, doorRecord, carRecord, user, msg) => u.Id == msg.VisitorId)
                .LeftJoin<SysOrg>((u, doorRecord, carRecord, user, msg, org) => user.OrgId == org.Id)
                ;
            //進場訪客數據
            var visEnterList = await query.Clone().Where(u => u.Status == ProcessStatus.Entered)
                        .GroupBy((u, doorRecord, carRecord, user, msg, org) => new { u.Visitor, u.Type, u.Vphone, u.Vcompany, u.VisitArea, u.DeptId, u.CarNo, user.RealName, user.Phone, org.Name, u.WaitToEnterTime })
                        .Select((u, doorRecord, carRecord, user, msg, org) => new
                        {
                            u.Visitor,
                            u.Vphone,
                            u.Vcompany,
                            u.CarNo,
                            u.Type,
                            u.VisitArea,
                            u.DeptId,
                            LaderName = user.RealName,
                            LaderPhone = user.Phone,
                            LaderOrg = org.Name,
                            wchatMessageCreateTime = SqlFunc.AggregateMax(msg.CreateTime),
                            VisitTime = SqlFunc.AggregateMax(u.VisitTime),
                            VendTime = SqlFunc.AggregateMax(u.VendTime),
                            lastDoorTime = SqlFunc.AggregateMax(doorRecord.eventTimeOk),
                            lastCarTime = SqlFunc.AggregateMax(carRecord.corssTimeOk),
                            WaitToEnterTime = SqlFunc.AggregateMax(carRecord.corssTimeOk),
                        })
                        .ToListAsync();
            //訪客等待數據
            var visWaitList = await query.Clone().Where((u, doorRecord, carRecord, user, msg) => (u.Status >= ProcessStatus.Agreed && u.Status < ProcessStatus.WaitToEnter) && (u.VisitTime >= today && u.VisitTime < today.AddDays(1)))
                          .GroupBy((u, doorRecord, carRecord, user, msg, org) => new { u.Visitor, u.Type, u.Vphone, u.Vcompany, u.VisitArea, u.DeptId, u.CarNo, user.RealName, user.Phone, u.Iphone, u.LeaderId, u.Staff, org.Id })
                          .Select((u, doorRecord, carRecord, user, msg, org) => new
                          {
                              u.Visitor,
                              u.Vphone,
                              u.Vcompany,
                              u.CarNo,
                              u.Type,
                              u.VisitArea,
                              u.LeaderId,
                              u.DeptId,
                              //Id = org.Id, //會報錯
                              LaderName = user.RealName,
                              LaderPhone = user.Phone,
                              u.Staff,
                              u.Iphone,
                              wchatMessageCreateTime = SqlFunc.AggregateMax(msg.CreateTime),
                              VisitTime = SqlFunc.AggregateMax(u.VisitTime),
                              VendTime = SqlFunc.AggregateMax(u.VendTime),
                              lastDoorTime = SqlFunc.AggregateMax(doorRecord.eventTimeOk),
                              lastCarTime = SqlFunc.AggregateMax(carRecord.corssTimeOk)
                          })
                         .ToListAsync();



            //异常访客 1.门卫已放行，1小时用户内没刷人脸信息   2.没有出门记录的访客    3.海康添加失败的用户
            //門衛掃碼確認後1小時內未入/出廠
            var ErrorVisitorOneHourNotInOuts = await _db.MyQueryable<VisitLog>().Where(u => u.Type < VisitorType.Customer && u.Status == ProcessStatus.WaitToEnter && (u.VisitTime >= today && u.VisitTime < today.AddDays(1)) && (u.WaitToEnterTime > now.AddMinutes(60) && u.WaitToEnterTime < now.AddMinutes(90)))
                            .Select((u) => new
                            {
                                u.Visitor,
                                u.Vphone,
                                u.Vcompany,
                                u.CarNo,
                                u.Type,
                                u.VisitArea,
                                u.LeaderId,
                                u.DeptId,
                                u.Staff,
                                u.Iphone,
                                ErrorInfo = "確認放行後超1小時未入廠"
                            })
                           .ToListAsync();

            //添加到海康異常
            var ErrorVisitorNotDoorAuths = await _db.MyQueryable<VisitLog>().Where((u) => u.Type < VisitorType.Customer && (u.Status >= ProcessStatus.Agreed && u.Status <= ProcessStatus.WaitToEnter) && (u.VisitTime >= today && u.VisitTime < today.AddDays(1)) && (u.AuthResultMessage.Contains("用戶權限添加到門禁設備失敗") || u.AuthResultMessage.Contains("用戶添加失敗")))
                        .Select((u) => new
                        {
                            u.Visitor,
                            u.Vphone,
                            u.Vcompany,
                            u.CarNo,
                            u.Type,
                            u.VisitArea,
                            u.LeaderId,
                            u.DeptId,
                            u.Staff,
                            u.Iphone,
                            ErrorInfo = u.AuthResultMessage
                        })
                       .ToListAsync();

            VisitorType[] types = new VisitorType[] { VisitorType.Build, VisitorType.Usual };
            var ErrorVisitorNotOutDoors = await _db.MyQueryable<DoorInOutRecord>()
                 .LeftJoin<VisitLog>((doorRecord, u) => SqlFunc.ToString(u.Id) == doorRecord.personId)
                 .Where((doorRecord, u) => u.WaitToEnterTime >= today && doorRecord.eventTimeOk >= today && u.Status == ProcessStatus.GoneOut && types.Contains(u.Type) &&
                 SqlFunc.Subqueryable<VisitLog>().Where(c => c.Vphone == u.Vphone && c.Status < ProcessStatus.GoneOut).NotAny())
                 .Select((doorRecord, u) => new
                 {
                     u.CarNo,
                     u.Visitor,
                     u.Vcompany,
                     u.Type,
                     doorRecord.devName,
                     doorRecord.eventTimeOk
                 }).ToListAsync();





            //有進場的記錄沒有出廠的記錄

            List<dynamic> ErrorVisitors = new List<dynamic>();
            foreach (var item in ErrorVisitorNotDoorAuths)
            {
                if (!ErrorVisitors.Any(r => r.Visitor == item.Visitor))
                {
                    string error = item.ErrorInfo;
                    if (item.ErrorInfo.Contains("用戶添加失敗"))
                        error = "添加到海康【臨時訪客】失敗，人臉權限無效";

                    if (item.ErrorInfo.Contains("用戶權限添加到門禁設備失敗"))
                        error = "添加到海康權限失敗，人臉權限無效";
                    ErrorVisitors.Add(new
                    {
                        Visitor = $"{item.Visitor}/{item.Type.GetDescription()}",
                        Vcompany = item.Vcompany,
                        ErrorInfo = error
                    });
                }
            }

            //掃碼放行超過一個小時沒有出入訪客 
            foreach (var item in ErrorVisitorOneHourNotInOuts)
            {
                if (!ErrorVisitors.Any(r => r.Visitor == item.Visitor))
                {
                    ErrorVisitors.Add(new
                    {
                        Visitor = $"{item.Visitor}/{item.Type.GetDescription()}",
                        Vcompany = item.Vcompany,
                        ErrorInfo = item.ErrorInfo
                    });
                }
            }

            ErrorVisitorNotOutDoors.GroupBy(r => r.Visitor).ForEach(r =>
            {
                ErrorVisitors = ErrorVisitors.Where(z => z.Visitor != r.Key).ToList();
                var lastDoorRecord = r.FirstOrDefault(c => c.eventTimeOk == r.Max(c => c.eventTimeOk));
                if (lastDoorRecord != null && !lastDoorRecord.devName.IsNullOrEmpty() && !lastDoorRecord.devName.Contains("出"))
                    ErrorVisitors.Add(new
                    {
                        Visitor = $"{lastDoorRecord.Visitor}/{lastDoorRecord.Type.GetDescription()}",
                        Vcompany = lastDoorRecord.Vcompany,
                        ErrorInfo = "此訪客沒有離廠記錄"
                    });
            });

            //当前场内访客
            var orgs = await _db.MyQueryable<SysOrg>().Where(r => r.Pid != 0).ToListAsync();
            Func<VisitorType, dynamic> areaVisitorEchart = (type) =>
              {
                  List<dynamic> dataList = new List<dynamic>();
                  if (type == VisitorType.Build)
                  {
                      //
                      var dicType = _db.LoadDictTypesByCode("build_area").Result;
                      dataList = dicType.SysDictDatas.Select(r => new
                      {
                          name = r.Value,
                          data = visEnterList.Where(c => c.Type == type && c.VisitArea == r.Value).Count()
                      }).OrderByDescending(r => r.data).ToDynamicList();

                  }
                  else if (type == VisitorType.Usual)
                  {
                      var enterUsualEable = visEnterList.Where(r => r.Type == type);

                      dataList = orgs.Where(r => r.Level == 2).Select(r => new
                      {
                          name = r.Name.Replace("@", ""),
                          data = visEnterList.Where(c => c.Type == type && c.LaderOrg == r.Name).Count()
                      }).OrderByDescending(r => r.data).ToDynamicList();
                  }
                  else if (type == VisitorType.Driver)
                  {
                      var driverEable = visEnterList.Where(r => r.Type == type && !r.VisitArea.IsNullOrEmpty());
                      var storageOrgs = orgs.Where(r => r.Pid == orgs.FirstOrDefault(c => c.Code == CommonConst.StorageCode).Id).ToList();
                      if (storageOrgs.Count() > 0)
                      {
                          var driverVisList = visEnterList.Where(c => c.Type == type).ToList().DeepClone();
                          storageOrgs.ForEach(r =>
                          {
                              dataList.Add(new
                              {
                                  name = r.Name.Replace("@", ""),
                                  data = driverVisList.Where(c => c.DeptId == r.Id).Count()
                                  //data = driverVisList.Where(c => c.VisitArea.Contains(r.Name)).Count()
                              });
                              //driverVisList = driverVisList.Where(c => !c.VisitArea.Contains(r.Name)).ToList(); //排除掉这个仓库，不然会在下个循环中又统计了这个仓库的信息
                          });
                      }
                  }
                  var visitorList = visEnterList.Where(r => r.Type == type);
                  return new
                  {
                      dimensions = new string[] { "name", "data" },
                      source = dataList.Where(r => r.data > 0).OrderByDescending(r => r.data).ToList()
                  };
              };


            Func<DateTime?, DateTime?, double> difMinute = (end, start) =>
            {
                if (!end.HasValue || !start.HasValue)
                    return 0;
                TimeSpan difference = end.Value - start.Value;
                double daysBetween = difference.TotalMinutes;
                if (daysBetween < 0)
                    return 0;

                return Math.Round(daysBetween, 0);
            };

            return new
            {
                Wait = visWaitList.OrderBy(r => r.wchatMessageCreateTime).Select(r => new string[] { $"{r.Visitor}/{r.Type.GetDescription()}", r.Vcompany, $" {(r.Staff.IsNullOrEmpty() ? JM(r.LaderName) : JM(r.Staff))}", $"{r.VisitTime?.ToString("HH:mm")} / {difMinute(DateTime.Now, r.VisitTime)}分鐘" }).ToList(),
                Usual = visEnterList.Where(r => r.Type == VisitorType.Usual).Select(r => new string[] { JM(r.Visitor), JMVcompany(r.Vcompany), JM(r.LaderName),r.VendTime?.ToString("MM-dd HH:mm"), r.lastDoorTime?.ToString("MM-dd HH:mm") }).ToList(),
                Driver = visEnterList.Where(r => r.Type == VisitorType.Driver).Select(r => new string[] { $"{r.Visitor}", r.Vcompany, r.VisitArea.Replace("@", ""), r.CarNo, JM(r.LaderName), (r.lastCarTime.HasValue ? r.lastCarTime.Value.ToString("MM-dd HH:mm") : r.lastDoorTime?.ToString("MM-dd HH:mm")) }).ToList(),
                Build = visEnterList.Where(r => r.Type == VisitorType.Build && ((r.lastDoorTime.HasValue && r.lastDoorTime.Value.Date == today) || (r.WaitToEnterTime.HasValue && r.WaitToEnterTime.Value.Date == today))).Select(r => new string[] { r.Visitor, r.Vcompany, r.VisitArea, $"{r.VisitTime.Value.ToString("MM-dd")}至{r.VendTime.Value.ToString("MM-dd")}", (r.lastDoorTime.HasValue ? r.lastDoorTime.Value.ToString("MM-dd HH:mm") : r.WaitToEnterTime?.ToString("MM-dd HH:mm")) }).ToList(),
                ErrorVisitors = ErrorVisitors.Select(r => new string[] { $"{r.Visitor}", r.Vcompany, r.ErrorInfo }),
                //折线图数据
                UsualEchart = areaVisitorEchart(VisitorType.Usual),
                DriverEchart = areaVisitorEchart(VisitorType.Driver),
                BuildEchart = areaVisitorEchart(VisitorType.Build)
            };
            //build_area
            //            { "dimensions":["product", "data1"],"source":
            //                    [{ "product":"Mon","data1":120},
            //{ "product":"Tue","data1":200},{ "product":"Wed","data1":150},
            //{ "product":"Thu","data1":80},{ "product":"Fri","data1":70},{ "product":"Sat","data1":110},{ "product":"Sun","data1":130}]}
            // "dimensions":["product", "data1", "data2"],"source":[{ "product":"Mon","data1":120,"data2":130},{ "product":"Tue","data1":200,"data2":130},{ "product":"Wed","data1":150,"data2":312},{ "product":"Thu","data1":80,"data2":268},{ "product":"Fri","data1":70,"data2":155},{ "product":"Sat","data1":110,"data2":117},{ "product":"Sun","data1":130,"data2":160}]}
            #region Delete
            //var visLogs = await _db.MyQueryable<VisitLog>()
            //    .LeftJoin<DoorInOutRecord>((u, doorRecord) => u.Id.ToString() == doorRecord.personId)
            //    .LeftJoin<HKCrossRecord>((u, doorRecord, carRecord) => u.CarNo == carRecord.plateNo)
            //    .LeftJoin<SysUser>((u, doorRecord, carRecord, user) => u.LeaderId == user.Id)
            //    .LeftJoin<WchatMessage>((u, doorRecord, carRecord, user, msg) => u.Id == msg.VisitorId)
            //    .WhereIF(type.HasValue, u => u.Type == type && u.Status == ProcessStatus.Entered)
            //    .WhereIF(!type.HasValue, (u, doorRecord, carRecord, user, msg) => u.Status == ProcessStatus.Check && (u.VisitTime >= today && u.VisitTime < today.AddDays(1)))
            //    .GroupBy((u, doorRecord, carRecord, user) => new { u.Visitor, u.Type, u.Vphone, u.Vcompany, u.CarNo, user.RealName, user.Phone })
            //    .Select((u, doorRecord, carRecord, user, msg) => new
            //    {
            //        u.Visitor,
            //        u.Vphone,
            //        u.Vcompany,
            //        u.CarNo,
            //        u.Type,
            //        LaderName = user.RealName,
            //        LaderPhone = user.Phone,
            //        wchatMessageCreateTime = SqlFunc.AggregateMax(msg.CreateTime),
            //        VisitTime = SqlFunc.AggregateMax(u.VisitTime),
            //        VendTime = SqlFunc.AggregateMax(u.VendTime),
            //        lastDoorTime = SqlFunc.AggregateMax(doorRecord.eventTimeOk),
            //        lastCarTime = SqlFunc.AggregateMax(carRecord.corssTimeOk)
            //    })
            //    .ToListAsync();
            //List<string[]> all = new List<string[]>();


            ////姓名,手機,所屬單位,對接人,入場時間
            //if (type == null)
            //    return visLogs.OrderBy(r => r.wchatMessageCreateTime).Select(r => new string[] { $"{r.Visitor}/{r.Type.GetDescription()}", r.Vcompany, $"{r.LaderName}/{r.LaderPhone}", $"{r.VisitTime?.ToString("HH:mm")} / {difMinute(DateTime.Now, r.wchatMessageCreateTime)}分鐘" }).ToList();
            //if (type == VisitorType.Usual)
            //    return visLogs.Select(r => new string[] { r.Visitor, r.Vphone, r.Vcompany, r.LaderName, r.lastDoorTime?.ToString("MM-dd HH:mm") }).ToList();
            //if (type == VisitorType.Driver)
            //    return visLogs.Select(r => new string[] { r.Visitor, r.Vphone, r.CarNo, r.Vcompany, r.LaderName, (r.lastCarTime.HasValue ? r.lastCarTime.Value.ToString("MM-dd HH:mm") : r.lastDoorTime?.ToString("MM-dd HH:mm")) }).ToList();
            //if (type == VisitorType.Build)
            //    return visLogs.Select(r => new string[] { r.Visitor, r.Vphone, r.CarNo, r.Vcompany, r.LaderName, (r.lastCarTime.HasValue ? r.lastCarTime.Value.ToString("MM-dd HH:mm") : r.lastDoorTime?.ToString("MM-dd HH:mm")) }).ToList();
            //return default(dynamic); 
            #endregion
        }
        private string JM(string str)
        {
            if (str.IsNullOrEmpty())
                return str;
            if (str == "null")
                return null;

            var len = str.Length;

            str = str.Substring(0, str.Length - 1);
            return str + "*";
        }

        private string JMVcompany(string str)
        {
            if (str.IsNullOrEmpty())
                return str;
            if (str == "null")
                return null;

            if (str.Length == 1)
                return str;

            var subLen= str.Length / 2;
            var res = str.Substring(0, subLen);

            for (int i = 0; i < str.Length-subLen; i++)
            {
                res += "*";
            }
            return res;
        }
        private string JMPhone(string str)
        {
            if (str.IsNullOrEmpty())
                return str;
            if (str == "null")
                return null;

            var len = str.Length;
            if (len <= 5)
                return str;

            str = str.Substring(0, str.Length - 4);
            return str + "****";
        }
        [HttpGet]
        public async Task<dynamic> LoadDoorRecords(int? type = null)
        {
            var _db = _rep.Context;
            var visitors = await _db.MyQueryable<VisitLog>()
                .Where(r => r.Status >= ProcessStatus.WaitToEnter && r.Status < ProcessStatus.GoneOut)
                .Includes(r => r.DoorRecords)
                .Includes(r => r.CardRecords)
                .ToListAsync();
            //switch
            return visitors.Select(r => new
            {
                typeName = r.Type.GetDescription(),
                r.Visitor,
                r.Vphone,
                r.CarNo,
                Vimg = GetVimg(r.Vimg),
                VendTime = r.VendTime?.ToString("yyyy-MM-dd"),
                VisitTime = r.VisitTime?.ToString("yyyy-MM-dd"),
                statusName = r.Status.GetDescription(),
                doorTime = r.DoorRecords.OrderByDescending(c => c.eventTimeOk).FirstOrDefault()?.eventTimeOk,
                carTime = r.CardRecords.OrderByDescending(c => c.corssTimeOk).FirstOrDefault()?.corssTimeOk
            }).ToList();
        }

        private string GetVimg(string vimg)
        {
            if (vimg.IsNullOrEmpty()) return default(string);
            if (currentHost.IsNullOrEmpty()) return vimg;

            var uri = new Uri(vimg);
            return $"{uri.Scheme}://{currentHost}{uri.AbsolutePath}";
        }

    }
}
